package mgodb

import (
	"github.com/facebookgo/inject"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	"github.com/pkg/errors"
	"jgt-oper/src/model"
	"jgt-oper/src/schema"
	"jgt-oper/src/service/mongo"
)

// cParking 停车位数据表
const cParking = "oper_parking"

// Parking 停车位管理
type Parking struct {
	DB *mongo.DB
}

// Init 初始化
func (a *Parking) Init(g *inject.Graph, db *mongo.DB) {
	a.DB = db

	// 初始化mongo索引
	a.DB.C(cParking, func(c *mgo.Collection) error {
		//c.EnsureIndex(mgo.Index{
		//	Key:    []string{"record_id"},
		//	Unique: true,
		//})
		//c.EnsureIndexKey("_id")
		//c.EnsureIndexKey("level_code")
		//c.EnsureIndexKey("deleted")
		return nil
	})

	var val model.IParking = a
	g.Provide(&inject.Object{Value: val, Name: "IParking"})
}

// Create 创建停车位节点
func (a *Parking) Create(item *schema.Parking) error {
	n := 0
	var err error
	//	检测重名
	err = a.DB.C(cParking, func(c *mgo.Collection) error {
		n, err = c.Find(bson.M{"node_name": item.NodeName, "deleted": 0, "node_type": item.NodeType}).Count()
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return errors.New("检测重名发生错误")
	}
	if n > 0 {
		return errors.New("发生重名")
	}
	err = a.DB.C(cParking, func(c *mgo.Collection) error {
		id, err := a.DB.IncrID(cParking)
		if err != nil {
			return err
		}
		item.ID = id
		return c.Insert(item)
	})
	if err != nil {
		return errors.Wrapf(err, "创建数据发生错误")
	}

	return nil
}

// Get 获取详情
func (a *Parking) Get(recordID string) (*schema.Parking, error) {
	item := new(schema.Parking)
	err := a.DB.C(cParking, func(c *mgo.Collection) error {
		return c.Find(bson.M{"record_id": recordID}).One(item)
	})
	if err != nil {
		if err == mgo.ErrNotFound {
			return nil, nil
		}
		return nil, errors.Wrapf(err, "精确查询数据发生错误")
	}
	return item, nil
}

// Update 更新数据
func (a *Parking) Update(recordID string, info map[string]interface{}) error {
	err := a.DB.C(cParking, func(c *mgo.Collection) error {
		return c.Update(bson.M{"record_id": recordID}, bson.M{"$set": info})
	})
	if err != nil {
		return errors.Wrapf(err, "更新数据发生错误")
	}
	return nil
}

// QueryIndex 查询停车场目录
func (a *Parking) QueryIndex(nodeType int) ([]*schema.Parking, error) {
	query := bson.M{
		"deleted":   0,
		"node_type": nodeType,
	}
	var items []*schema.Parking
	err := a.DB.C(cParking, func(c *mgo.Collection) error {

		return c.Find(query).Sort("id").Skip(0).Limit(50).All(&items)
	})
	if err != nil {
		return nil, err
	}

	return items, nil
}

// QueryChildrenNodes 查询指定停车位节点的所有子节点
func (a *Parking) QueryChildrenNodes(recordID string) ([]*schema.Parking, error) {
	query := bson.M{
		"deleted":   0,
		"parent_id": recordID,
	}
	var items []*schema.Parking
	err := a.DB.C(cParking, func(c *mgo.Collection) error {

		return c.Find(query).Sort("id").Skip(0).Limit(50).All(&items)
	})
	if err != nil {
		return nil, err
	}

	return items, nil
}

// QueryParentNodes 查询指定节点的所有的父节点
func (a *Parking) QueryParentNodes(recordID string) ([]*schema.Parking, error) {
	query := bson.M{
		"deleted":   0,
		"parent_id": recordID,
	}

	var items []*schema.Parking
	err := a.DB.C(cPark, func(c *mgo.Collection) error {
		return c.Find(query).Sort("level_code").All(&items)
	})
	if err != nil {
		return nil, errors.Wrapf(err, "根据上级查询数据发生错误")
	}

	return items, nil
}
